package main

import (
	"context"
	"fmt"
	clientv3 "go.etcd.io/etcd/client/v3"
	"log"
	"time"
)

func main() {
	//PutGet()
	//WatchDemo()
	//LeaseDemo()
	keepAliveDemo()
}
func PutGet() {
	client, err := clientv3.New(clientv3.Config{Endpoints: []string{"127.0.0.1:2379"},
		DialTimeout: 5 * time.Second})
	if err != nil {
		// handle error!
		fmt.Printf("connect to etcd failed, err:%v\n", err)
		return
	}
	fmt.Println("connect to etcd success")
	defer client.Close()
	//put
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	_, err = client.Put(ctx, "greeting", "ybl is greeting now")
	if err != nil {
		fmt.Printf("put to etcd failed, err:%v\n", err)
		return
	}
	cancel()
	//get
	ctx, cancel = context.WithTimeout(context.Background(), time.Second)
	response, err := client.Get(ctx, "greeting")
	cancel()
	if err != nil {
		fmt.Printf("get from etcd failed, err:%v\n", err)
		return
	}
	for _, kv := range response.Kvs {
		fmt.Printf("%s:%s\n", kv.Key, kv.Value)
	}
}
func WatchDemo() {
	client, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: time.Second * 5,
	})
	if err != nil {
		fmt.Printf("connect to etcd failed, err:%v\n", err)
		return
	}
	fmt.Println("connect to etcd success")
	defer client.Close()

	watch := client.Watch(context.Background(), "greeting") // <-chan  watchresponse
	for c := range watch {                                  //for  range  检测 chan
		for _, ev := range c.Events {
			fmt.Printf("Type: %s Key:%s Value:%s\n", ev.Type, ev.Kv.Key, ev.Kv.Value)
		}
	}
}

//lease 租约

func LeaseDemo() {
	client, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: time.Second * 5,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("connect to etcd success.")
	defer client.Close()

	//创建一个5秒的租约   grant=同意
	grant, err := client.Grant(context.Background(), 5)
	if err != nil {
		log.Fatal(err)
	}
	// 5秒钟之后, lease 这个key就会被移除
	_, err = client.Put(context.TODO(), "lease", "test lease", clientv3.WithLease(grant.ID)) //这里就用到了option模式

	if err != nil {
		log.Fatal(err)
	}
}
func keepAliveDemo() {
	client, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: time.Second * 5,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("connect to etcd success.")
	defer client.Close()
	grant, _ := client.Grant(context.TODO(), 5)
	client.Put(context.TODO(), "lease", "lease value", clientv3.WithLease(grant.ID))
	alive, err := client.KeepAlive(context.TODO(), grant.ID) //只要这个函数在 这个值就一直在，这个keepalive就是让值存在 但不是永久
	if err != nil {
		log.Fatal(err)
	}
	for {
		ka := <-alive
		fmt.Println("ttl:", ka.TTL)
	}
}
